package cc.rengu.redp.hawk.algorithm;

import cc.rengu.redp.hawk.domain.TimestampData;
import cc.rengu.redp.hawk.service.IndexAlgorithm;
import cc.rengu.redp.hawk.utils.HawkUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 变化速率算法
 *
 * 计算指定周期内增量与时间（秒）的比值
 */
@Slf4j
public class RateOfChange implements IndexAlgorithm {

    private final static String TAG_INPUT_INDEX_NAME = "inputIndexName";
    private final static String TAG_PERIOD = "period";

    @Override
    public String paramsSample() {
        JSONObject jsonObject = new JSONObject();
        /**
         * 定义配置参数：参与计算的指标名
         */
        jsonObject.put(TAG_INPUT_INDEX_NAME, "?");
        /**
         * 定义配置参数：时间长度（秒）
         */
        jsonObject.put(TAG_PERIOD, "?");
        return jsonObject.toJSONString();
    }

    @Override
    public String algorithmChineseName() {
        return "变化速率";
    }

    @Override
    public Float run(JSONObject algParams, Map<String, List<TimestampData>> timelineData, JSONObject currData) {
        //校验参数
        String inputIndexName = algParams.getString(TAG_INPUT_INDEX_NAME);
        String periodStr = algParams.getString(TAG_PERIOD);
        if (StringUtils.isBlank(inputIndexName) || StringUtils.isBlank(periodStr)) {
            log.warn("invalid configuration. algParams:[{}]", algParams.toJSONString());
            return 0.0f;
        }
        Long period = Long.valueOf(periodStr);
        if (period == null || period <= 0) {
            log.warn("invalid period. period:[{}]", period);
            return 0.0f;
        }
        Float currIndex = HawkUtil.jsonObjectValueToFloat(currData.get(inputIndexName));
        if (currIndex == null) {
            log.warn("current index data is null. currData:[{}]", currData.toJSONString());
            return 0.0f;
        }

        //获得指标的历史数据
        List<TimestampData> timestampDataList = timelineData.get(inputIndexName);
        if (timestampDataList == null || timestampDataList.size() == 0) {
            return 0.0f;
        }
        //历史数据中的时间区间右值
        TimestampData maxTimestampData = timestampDataList.get(timestampDataList.size() - 1);
        //计算时间区间左值
        Long minTimestamp = maxTimestampData.getTimestamp() - period * 1000;
        //过滤有效的区间数据
        List<TimestampData> validData = timestampDataList
                .stream()
                .filter(i -> i.getTimestamp() >= minTimestamp)
                .collect(Collectors.toList());
        if (validData.size() > 0) {
            //计算增量
            Float delta = currIndex - validData.get(0).getIndexData();
            //变化速率
            return delta / period;
        } else {
            return 0.0f;
        }
    }
}
